#pragma once
#include <iostream> 
#include <cstring>
#include <unistd.h>
#include <strings.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

namespace ns_tcpclient {
    class TcpClient {
        private:
            uint16_t dest_port;
            std::string dest_ip;
            int sock;
        public:
            TcpClient(uint16_t port, std::string ip)
                :dest_port(port)
                ,dest_ip(ip)
            {}

            void InitTcpClient() {
                sock = socket(AF_INET, SOCK_STREAM, 0);
                if (sock < 0) {
                    std::cerr << "sock error" << std::endl;
                    exit(2);
                }
                //client不需要自己bind，发起连接的时候，OS自动进行相关绑定
                //client不需要自己listen，因为没人连接他
                //client不需要accept，因为没人来连接他
            }

            void Start() {
                // 填对方服务器信息
                struct sockaddr_in svr;
                bzero(&svr, sizeof(svr));
                svr.sin_family = AF_INET;
                svr.sin_port = htons(dest_port);
                svr.sin_addr.s_addr = inet_addr(dest_ip.c_str());
                // 发起连接请求
                if (connect(sock, (struct sockaddr*)&svr, sizeof(svr)) == 0) {
                    std::cout << "success connect" << std::endl;
                } else {
                    std::cerr << "fail connect" << std::endl;
                    return;
                }

                // 连接成功，处理完成业务逻辑
                while (true) {
                    char buffer[1024] = {0};
                    std::cout << "请你输入# ";
                    fflush(stdout);
                    ssize_t s = read(0, buffer, sizeof(buffer)-1);
                    if (s > 0) {
                        buffer[s - 1] = 0;
                        write(sock, buffer, strlen(buffer));

                        ssize_t rs = read(sock, buffer, sizeof(buffer));
                        if (rs > 0) {
                            buffer[rs] = 0;
                            std::cout << buffer << std::endl;
                        } else {
                            std::cout << "server close" << std::endl;
                            break;
                        }
                    }
                }
            }

            ~TcpClient() {
                if (sock < 0) {
                    close(sock);
                }
            }
    };
}
